//封装一个axios请求。
import axios from "axios"
import localstorage from "../../base/utils/storage";
import { RefreshToken } from "../../domain/login/service";
const instance = axios.create({
  baseURL: "http://114.55.105.248/api",
  timeout: 3000,
});

const CancelToken = axios.CancelToken;
declare module "axios" {
  interface InternalAxiosRequestConfig {
    getCancelMethod?: (cancel: (message?: string) => void) => void;
  }
}
const getAccessToken = () => localstorage.get("accesstoken");
const getRefreshToken = () => localstorage.get("refreshToken");
let isRefreshing = false;
let failedQueue: {
  resolve: (value: unknown) => void;
  reject: (reason?: unknown) => void;
}[] = [];

const processQueue = (error: unknown, token = null) => {
  failedQueue.forEach((prom) => {
    if (error) {
      prom.reject(error);
    } else {
      prom.resolve(token);
    }
  });

  failedQueue = [];
};

// 刷新 access_token 的函数
const refreshAccessToken = async () => {
  try {
    const refresh_token =getRefreshToken()
    const { data } = await RefreshToken(refresh_token);
    const newAccessToken = data.access_token;

    // 更新 access_token 和 localStorage
    localstorage.set("accesstoken", newAccessToken);
    console.log("Access token refreshed successfully");
  } catch (error) {
    console.error("Failed to refresh access token:", error);
    // 如果刷新失败，清除登录状态并跳转到登录页
    localstorage.remove("accesstoken");
    localstorage.remove("refreshToken");
    window.location.href = "/";
  }
};

// 设置定时刷新
const setupTokenRefresh = () => {
  const refreshInterval = 1000 * 60 * 5; // 每 5 分钟刷新一次

  const intervalId = setInterval(async () => {
    const access_token = getAccessToken();
    const refresh_token = getRefreshToken()

    if (!refresh_token) {
      // 如果 refresh_token 不存在，清除登录状态并跳转到登录页
      localstorage.remove("accesstoken");
      localstorage.remove("refreshToken");
      window.location.href = "/";
      clearInterval(intervalId);
      return;
    }

    if (access_token && refresh_token) {
      await refreshAccessToken();
    }
  }, refreshInterval);

  return intervalId;
};

const startRefresh = () => {
  const refresh_token = getRefreshToken()
  const access_token =getAccessToken()
  // 启动定时刷新
  if (access_token && refresh_token) {
    setupTokenRefresh();
  }
};

startRefresh()
//处理url中的参数
instance.interceptors.request.use(
  (config) => {
    console.log(config, "request");
    let url = config.url;
    const params = config.params || {}; // Ensure params is an object

    if (url) {
      url = url.replace(/\{(\w+)\}/g, (_match, $1) => {
        const value = params[$1];
        if (value === undefined || value === null) {
          throw new Error(`Missing required parameter: ${$1}`);
        }
        delete params[$1];
        return encodeURIComponent(value);
      });
    }

    config.url = url;
    return config;
  },
  (error) => {
    // Handle request error here
    console.error("Request  interceptor error:", error);
    return Promise.reject(error);
  }
);

//提取请求url中的method
instance.interceptors.request.use(
  (config) => {
    if (!config.url) {
      throw new Error("URL is required");
    }

    const urlConfig = config.url.split(/\s+/);
    if (urlConfig.length > 1) {
      const method = urlConfig[0].toLowerCase();
      if (!["get", "post", "put", "delete"].includes(method)) {
        throw new Error(`Invalid HTTP method: ${method}`);
      }

      config.method = method;
      config.url = urlConfig.slice(1).join("  "); // Handle cases where the URL contains multiple spaces
    }

    return config;
  },
  (error) => {
    // Handle request error here
    console.error("Request  interceptor error:", error);
    return Promise.reject(error);
  }
);

//处理获取请求取消的配置
instance.interceptors.request.use(
  (config) => {
    if (
      config.getCancelMethod &&
      typeof config.getCancelMethod === "function"
    ) {
      try {
        config.cancelToken = new CancelToken(function executor(c) {
          config.getCancelMethod!(c);
        });

        delete config.getCancelMethod; //  Clean up the custom property after use to avoid potential side effects or memory leaks over time due to lingering references in memory that are no longer needed but still being held onto by some part of your application's runtime environment etc...
      } catch (error) {
        console.error("Failed  to set cancel token:", error);
        throw new Error("Failed to set cancel token");
      }
    }

    return config;
  },
  (error) => {
    // Handle request error here
    console.error("Request  interceptor error:", error);
    return Promise.reject(error);
  }
);

//请求拦截，设置Authorization请求头。
instance.interceptors.request.use((config) => {
  const access_token = localstorage.get("accesstoken"); //从localstorage中获取token，后续可以放进store中。
  if (access_token) {
    config.headers.Authorization = `Bearer ${access_token}`; // 动态设置 Authorization
  }
  return config;
});

//响应拦截，刷新access_token,token过期清除token并返回登录页。
instance.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;

    if (error.response.status === 401 && !originalRequest._retry) {
      if (isRefreshing) {
        // 如果正在刷新，将请求加入队列
        return new Promise((resolve, reject) => {
          failedQueue.push({ resolve, reject });
        })
          .then((token) => {
            originalRequest.headers.Authorization = `Bearer ${token}`;
            return instance(originalRequest);
          })
          .catch((err) => Promise.reject(err));
      }

      originalRequest._retry = true;
      isRefreshing = true;

      try {
        const refresh_token = localstorage.get("refreshToken");
        if (!refresh_token) {
          // 如果 refresh_token 不存在，清除登录状态并跳转到登录页
          localstorage.remove("accesstoken");
          localstorage.remove("refreshToken");
          window.location.href = "/";
        }

        const { data } = await RefreshToken(refresh_token);
        console.log(data,'data');
        
        const newAccessToken = data.data.access_token;

        // 更新 access_token 和 localStorage
        localstorage.set("accesstoken", newAccessToken);
        processQueue(null, newAccessToken); // 处理队列中的请求
        originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
        return instance(originalRequest);
      } catch (refreshError) {
        // 如果刷新失败，清除登录状态并跳转到登录页
        console.log(11111);
        localstorage.remove("accesstoken");
        localstorage.remove("refreshToken");
        window.location.href = "/";
        processQueue(refreshError, null); // 处理队列中的请求
        return Promise.reject(refreshError);
      } finally {
        isRefreshing = false;
      }
    }

    return Promise.reject(error);
  }
);

export default instance;
